import random
import string
from django.http import Http404
from rest_framework import status
# from zope.interface.ro._ROComparison import Item

from Student.models import *
# 导入Q查询
from django.db.models import Q, Count
# 导入uuid类
import uuid
# 导入哈希库
import hashlib
# 导入Setting
from django.conf import settings
# 导入os
import os
from School.serializers import StudentSerializer
from School.serializers import ApplicationSerializer
from rest_framework.views import APIView
from rest_framework.response import Response
from .models import School
import requests
# import datetime
from datetime import datetime, timedelta, timezone as dt_timezone  # 使用标准库的timezone
import jwt
from .serializers import *
from School.serializers import SchoolSerializer
from .pagination import CustomPagination
from django.db import transaction



# def generate_unique_nickname():
#     prefix = "一位神秘的同学"
#     suffix = ''.join(random.choices(string.digits, k=5))
#     return prefix + suffix
def generate_unique_nickname():
    prefix = "一位神秘的同学"
    while True:
        suffix = ''.join(random.choices(string.digits, k=5))
        nickname = prefix + suffix

        # 检查昵称是否唯一
        if not Student.objects.filter(nickname=nickname).exists():
            return nickname

        # 小程序登录---start


class WeChatLoginView(APIView):
    authentication_classes = []

    def post(self, request):
        code = request.data.get('code')
        # session_key = request.data.get('session_key')
        appid = 'wx42b63bbee9711c1c'
        secret = '783a303830d1db1ad147b89ccc8bf554'
        school = request.data.get('school')

        try:
            school_instance = School.objects.get(name=school)  # 获取对应的 School 实例
            school_id = school_instance.id  # 获取该实例的 id
        except School.DoesNotExist:
            return Response({'error': '学校未找到'}, status=404)

        url = f'https://api.weixin.qq.com/sns/jscode2session?appid={appid}&secret={secret}&js_code={code}&grant_type=authorization_code'

        try:
            response = requests.get(url)
            response.raise_for_status()
            data = response.json()
        except requests.RequestException as e:
            return Response({'error': str(e)}, status=500)

        openid = data.get('openid')
        if not openid:
            return Response({'error': '获取 openid 失败'}, status=400)

        student = Student.objects.filter(sno=openid).first()
        if student:
            token = get_token(openid, school_id)
            return Response({'code': 1001, 'token': token, 'msg': '登录成功！', 'openid': openid})
        nickname = generate_unique_nickname()
        obj_student = Student(sno=openid, name=None, gender=None,
                               mobile=None,
                              address=None, image=None,
                              school_id=school_id, nickname=nickname)
        obj_student.save()
        token = get_token(openid, school_id)
        return Response({'code': 1001, 'token': token, 'msg': '注册并登录成功！', 'openid': openid})


# 小程序登录---end

# 获取token---start
from datetime import datetime, timedelta
from django.utils import timezone

def get_token(openid, school_id):
    salt = settings.SECRET_KEY
    headers = {
        'typ': 'JWT',
        'alg': 'HS256'
    }
    # 获取当前时间并转换为时区感知
    exp_time = timezone.now() + timedelta(hours=24)  # Django 方法处理时区
    payload = {
        'openid': openid,
        'school_id': school_id,
        'exp': exp_time,
    }
    token = jwt.encode(payload=payload, key=salt, algorithm='HS256', headers=headers)
    return token




# 获取token---end

# 帖子视图---start
class PostView(APIView):
    # authentication_classes = []

    def post(self, request):
        # 获取用户信息
        global contact
        payload = request.user
        print(request.data)
        school_id = payload['school_id']
        # school_id = 1
        student_id = payload['openid']
        # student_nickname = 'os-t-7X1mFa3M2H82nazBNME7vYE'
        data = request.data
        title = data.get('title')
        content = data.get('content')
        create_time = data.get('created_at')
        category_name = data.get('category')
        typ = data.get('type')
        number = data.get('number')
        # 定义默认值为 None 的 contact 变量
        contact = None
        if typ:
            contact = Contact.objects.create(type=typ, number=number)
            contact_id = contact.id
        try:
            category_id = Category.objects.get(name=category_name).id
        except Category.DoesNotExist:
            return Response({'code': -1, 'msg': '类别不存在！'}, status=status.HTTP_400_BAD_REQUEST)
        # 创建帖子
        # 在创建 Post 对象时检查 contact 是否为 None
        post = Post(title=title, content=content, created_at=create_time,
                    likes=0, category_id=category_id, student_id=student_id,
                    school_id=school_id, contact=contact if contact else None)
        post.save()
        post_id = post.id
        return Response({'code': 1001, 'msg': "发帖成功", 'id': post_id}, status=status.HTTP_201_CREATED)

    def get(self, request):
        try:
            cid = request.query_params.get('id')
            print(cid)
        except Exception as e:
            print(e)
            return Response({'error': str(e)}, status=400)
        payload = request.user
        print(payload)
        school_id = payload['school_id']
        # school_id = 1
        if cid == '2':
            posts = Post.objects.filter(Q(school_id=school_id)).order_by('-created_at')
        posts = Post.objects.filter(Q(school_id=school_id) & Q(category_id=cid))
        paginator = CustomPagination()
        paginated_posts = paginator.paginate_queryset(posts, request)
        if paginated_posts is None:
            return Response([])
        serializer = PostSerializer(paginated_posts, many=True)
        return paginator.get_paginated_response(serializer.data)

    def get(self, request):
        try:
            cid = request.query_params.get('id')
            print(cid)
        except Exception as e:
            print(e)
            return Response({'error': str(e)}, status=400)
        payload = request.user
        print(payload)
        school_id = payload['school_id']
        # school_id = 1
        if cid == '2':
            posts = Post.objects.filter(Q(school_id=school_id)).order_by('-created_at')
        posts = Post.objects.filter(Q(school_id=school_id) & Q(category_id=cid))
        paginator = CustomPagination()
        paginated_posts = paginator.paginate_queryset(posts, request)
        if paginated_posts is None:
            return Response([])
        serializer = PostSerializer(paginated_posts, many=True)
        return paginator.get_paginated_response(serializer.data)


# 帖子视图---end

# 获取个人页的帖子---start
class Getmyposts(APIView):
    def get(self, request):
        payload = request.user
        openid = payload['openid']
        student = Student.objects.get(sno=openid)
        posts = Post.objects.filter(student=student).order_by('-created_at')
        paginator = CustomPagination()
        paginated_posts = paginator.paginate_queryset(posts, request)
        if paginated_posts is None:
            return Response([])
        serializer = PostSerializer(paginated_posts, many=True)
        return paginator.get_paginated_response(serializer.data)


# 获取个人页的帖子---end

# 评论视图---start
class CommentView(APIView):
    def post(self, request):
        payload = request.user
        print(payload)
        openid = payload['openid']
        student = Student.objects.get(sno=openid)
        data = request.data
        post_id = data.get('post')
        text = data.get('text')
        school = student.school
        # school = School.objects.get(id=school_id)
        avatar = data.get('avatar')
        parent_id = data.get('parent')
        try:
            parent = Comment.objects.get(id=parent_id)
        except Comment.DoesNotExist:
            parent = None
        created_at = data.get('created_at')
        student_id = data.get('student')
        # likes = data.get('likes')
        comment = Comment.objects.create(
            post_id=post_id,
            text=text,
            avatar=avatar,
            school=school,
            student=student,
            created_at=created_at,
            parent=parent,
            # likes=likes,
        )
        return Response({'code': 1001, 'message': '评论成功'})

    def get(self, request):
        post_id = request.query_params.get('post_id')
        # print(post_id)
        post = Post.objects.get(id=post_id)
        # print(post)
        comments = Comment.objects.filter(post=post).order_by('-created_at')
        serializer = CommentSerializer(comments, many=True)
        print(serializer.data)
        return Response({'code': 1001, 'message': serializer.data})

    def delete(self, request):
        data = request.query_params
        comment_id = data.get('id')
        comment = Comment.objects.filter(id=comment_id)
        # for comment in comments:(这句话在要删除的数据很多的时候用，减轻删除数据的压力，要不然django会打算一次性删除所有的，这里只有一个数据所以没问题）
        comment.delete()
        return Response({'code': 1001, 'message': '删除成功'})


# 评论视图---end


# 绑定判断身份---start
class IdentityView(APIView):
    def get(self, request):
        payload = request.user
        openid = payload['openid']
        student = Student.objects.get(sno=openid)
        if not student.st_sno and not student.name:
            return Response({'code': -1, 'message': '认证失败，未已绑定'})
        return Response({'code': 1001, 'message': '用户已认证，绑定'})

    def post(self, request):
        payload = request.user
        openid = payload['openid']
        student = Student.objects.get(sno=openid)
        data = request.data
        print(request.data)
        student.name = data.get('name')
        student.st_sno = data['st_sno']
        student.save()
        image = request.FILES.get('image')
        if image:
            # 获得一个唯一的名字： uuid +hash
            new_name = get_random_str()
            # 准备写入的URL
            file_path = os.path.join(settings.MEDIA_ROOT, 'st_avatar', new_name + os.path.splitext(image.name)[1])
            # 开始写入到本次磁盘
            try:
                f = open(file_path, 'wb')
                # 多次写入
                for i in image.chunks():
                    f.write(i)
                # 要关闭
                f.close()
                # 返回
                student.image = new_name + os.path.splitext(image.name)[1]
                student.save()
                return Response({'code': 1001, 'name': new_name + os.path.splitext(image.name)[1]})
            except Exception as e:
                return Response({'code': -1, 'msg': str(e)})
        return Response({'code': 1001, 'message': '绑定成功'})


# 绑定判断身份---end

class IdentyInfoView(APIView):
    def get(self, request):
        payload = request.user
        openid = payload['openid']
        student = Student.objects.get(sno=openid)
        serializer = StudentSerializer(student)
        return Response({'code': 1001, 'message': serializer.data})


# 搜索帖子---start
class PostSearchView(APIView):
    def get(self, request):
        query = request.query_params.get('search', None)
        if query:
            posts = Post.objects.filter(
                Q(title__icontains=query) |
                Q(content__icontains=query) |
                Q(student__name__icontains=query) |
                Q(school__name__icontains=query) |
                Q(category__name__icontains=query)
            )
            serializer = PostSerializer(posts, many=True)
            return Response({'code': 1001, "message": serializer.data})
        else:
            return Response({'code': -1, "message": '搜索内容不能为空'})


# 搜索帖子---end


# 热评---start
class HotCommentView(APIView):
    def get(self, request):
        post_id = request.query_params.get('post_id')
        comments = Comment.objects.filter(post_id=post_id).order_by('-likes')
        serializer = CommentSerializer(comments, many=True)
        return Response({'code': 1001, 'type': 0, 'message': serializer.data})


# 热评---end


# 热帖---start
class HotPostView(APIView):
    def get(self, request):
        payload = request.user
        school_id = payload['school_id']
        count = request.query_params.get('count')
        count = int(count)
        posts = Post.objects.filter(school_id=school_id).order_by('-likes')[:count]
        serializer = PostSerializer(posts, many=True)
        return Response({'code': 1001, 'message': serializer.data})


# 热帖---end


class CommentLikeView(APIView):
    def post(self, request):
        data = request.data
        comment_id = data.get('id')
        payload = request.user
        student_id = payload['openid']
        student = Student.objects.get(sno=student_id)
        try:
            comment = Comment.objects.get(id=comment_id)
        except Comment.DoesNotExist:
            return Response({'code': 1002, 'message': '评论不存在'}, status=404)
        # 增加 likes 计数
        comment.likes += 1
        comment.save()
        payload = request.user
        student_id = payload['openid']
        comment_like = CommentLike.objects.create(comment=comment, student=student)
        return Response({'code': 1001, 'message': '点赞成功'})


class CommentUnLike(APIView):
    def post(self, request):
        data = request.data
        print(data)
        comment_id = data.get('id')
        print(comment_id)
        try:
            comment = Comment.objects.get(id=comment_id)
        except Comment.DoesNotExist:
            return Response({'code': 1002, 'message': '评论不存在'}, status=404)

        comment.likes -= 1
        comment.save()

        payload = request.user
        student_id = payload['openid']

        # 删除点赞记录
        try:
            comment_like = CommentLike.objects.filter(comment=comment, student=student_id).first()
            if comment_like:
                comment_like.delete()
            return Response({'code': 1001, 'message': '取消成功'})

        except CommentLike.DoesNotExist:
            return Response({'code': 1002, 'message': '没有点赞记录，无法取消'}, status=404)


class LikePostView(APIView):
    def post(self, request):
        try:
            post_id = request.data.get('post_id')
            post = Post.objects.get(id=post_id)
            payload = request.user
            student_id = payload['openid']
            student = Student.objects.get(sno=student_id)
            # 检查是否已经点赞
            if not PostLike.objects.filter(post=post, student=student).exists():
                PostLike.objects.create(post=post, student=student)
                post.likes += 1
                post.save()
                return Response({'code': 1001, 'message': '点赞成功'})
            else:
                return Response({'code': -1, 'message': '已经点赞过了'})
        except Post.DoesNotExist:
            return Response({'code': -1, 'message': '帖子不存在'})
        except Exception as e:
            print(e)
            return Response({'code': -1, 'message': '点赞操作出错', 'error': str(e)})


class UnlikePostView(APIView):
    def post(self, request):
        try:
            post_id = request.data.get('post_id')
            post = Post.objects.get(id=post_id)
            payload = request.user
            student_id = payload['openid']
            student = Student.objects.get(sno=student_id)
            like = PostLike.objects.filter(post=post, student=student).first()
            if like:
                like.delete()
                post.likes -= 1
                post.save()
                return Response({'code': 1001, 'message': '取消点赞成功'})
            else:
                return Response({'code': -1, 'message': '还没有点赞过'})
        except Post.DoesNotExist:
            return Response({'code': -1, 'message': '帖子不存在'})
        except Exception as e:
            return Response({'code': -1, 'message': '取消点赞操作出错'})


# 上传提帖子图片---start
class PostImageUploadView(APIView):
    """上传帖子图片"""

    def post(self, request):
        """接收上传的文件"""
        # 接收上传的文件
        rev_file = request.data.get('image')
        post_id = request.data.get('post_id')
        print(rev_file)
        # 判断，是否有文件
        if not rev_file:
            return Response({'code': 0, 'msg': '图片不存在！'})
        # 获得一个唯一的名字： uuid +hash
        new_name = get_random_str()
        # 准备写入的URL
        file_path = os.path.join(settings.MEDIA_ROOT, 'post_image', new_name + os.path.splitext(rev_file.name)[1])
        print(file_path)
        # 开始写入到本次磁盘
        try:
            f = open(file_path, 'wb')
            # 多次写入
            for i in rev_file.chunks():
                f.write(i)
            # 要关闭
            f.close()
            # 返回
            post = Post.objects.get(id=post_id)
            PostImage.objects.create(post=post, image=new_name + os.path.splitext(rev_file.name)[1])
            return Response({'code': 1001, 'name': new_name + os.path.splitext(rev_file.name)[1]})

        except Exception as e:
            return Response({'code': -1, 'msg': str(e)})


# 上传提帖子图片---end

# 获取随机数，用于图片上传---stat
def get_random_str():
    uuid_val = uuid.uuid4()
    uuid_str = str(uuid_val).encode('utf-8')
    md5 = hashlib.md5()
    md5.update(uuid_str)
    return md5.hexdigest()


# 获取随机数，用于图片上传---end


# 获取分类信息---start
class GetCategoryListView(APIView):
    def get(self, request):
        try:
            categories = Category.objects.all()
            serializer = CategorySerializer(categories, many=True)
            return Response({'code': 1001, 'data': serializer.data})
        except Exception as e:
            return Response({'code': -1, 'msg': "获取分类信息出现异常，具体错误：" + str(e)})


# 获取分类信息---send


# 获取帖子点赞信息---start
class GetPostLikeView(APIView):
    def get(self, request):
        try:
            post_likes = PostLike.objects.all()
            serializer = PostLikeSerializer(post_likes, many=True)
            return Response({'code': 1001, 'data': serializer.data})
        except Exception as e:
            return Response({'code': -1, 'msg': "获取点赞信息出现异常，具体错误：" + str(e)})


# 获取帖子点赞信息---end

# 上传学生头像---start
class UploadStudentAvatarView(APIView):
    def post(self, request):
        payload = request.user
        student_id = payload['openid']
        student = Student.objects.get(sno=student_id)
        # 获取上传的文件
        avatar = request.FILES.get('avatar')
        # 生成随机文件名
        new_name = get_random_str()
        # 准备写入的URL
        file_path = os.path.join(settings.MEDIA_ROOT, 'st_avatar', new_name + os.path.splitext(avatar.name)[1])
        # 开始写入到本次
        try:
            f = open(file_path, 'wb')
            # 多次写入
            for i in avatar.chunks():
                f.write(i)
            # 要关闭
            f.close()
            # 返回
            student.image = new_name + os.path.splitext(avatar.name)[1]
            student.save()
            return Response({'code': 1001, 'data': new_name + os.path.splitext(avatar.name)[1]})
        except Exception as e:
            print(e)
            return Response({'code': -1, 'msg': str(e)})


# 上传学生头像---end


# 上传学生昵称---start
class UploadNickname(APIView):
    def post(self, request):
        payload = request.user
        student_id = payload['openid']
        try:
            student = Student.objects.get(sno=student_id)
            new_nickname = request.data.get('nickname')
            if Student.objects.filter(nickname=new_nickname).exists():
                return Response({'code': 1001, 'codecode': 1, 'msg': '该昵称已被使用，请选择一个不同的昵称'})
            student.nickname = new_nickname
            print('匿名', student.nickname)
            student.save()
        except Exception as e:
            print(e)
            return Response({'code': -1, 'msg': str(e)})
        return Response({'code': 1001,'codecode': 0, 'message': '修改成功'})


# 上传学生昵称---end


# 获取学生主页信息---start
class GetStudentInfo(APIView):

    def get(self, request):
        payload = request.user
        student_id = payload['openid']
        student = Student.objects.get(sno=student_id)
        post_count = Post.objects.filter(student_id=student_id).count()
        posts = Post.objects.filter(student_id=student_id)
        # 使用聚合函数Count计算student的帖子获得的总点赞数
        total_likes = PostLike.objects.filter(post__student=student).aggregate(total_likes=Count('id'))['total_likes']
        school = School.objects.get(id=student.school_id)
        nickname = student.nickname
        avatar = student.image
        return Response(
            {'code': 1001,
             'data': {'post_count': post_count, 'like_count': total_likes, 'school': school.name, 'nickname': nickname,
                      'avatar': avatar}})


# 获取学生主页信息---end


class ProductDetailAPIView(APIView):
    authentication_classes = []

    def get(self, request):
        try:
            product_id = request.query_params.get('product_id')
            print(product_id)
            product = Product.objects.get(id=product_id)
            serializer = ProductSerializer(product)
            return Response(serializer.data)
        except Product.DoesNotExist:
            return Response({'error': 'Product not found'}, status=404)


class ProductListAPIView(APIView):
    # authentication_classes = []

    def get(self, request):
        products = Product.objects.all()
        try:
            serializer = ProductSerializer(products, many=True)
            return Response({'code': 1001, 'data': serializer.data})
        except Exception as e:
            return Response({'code': -1, 'msg': str(e)})

    def post(self, request):
        payload = request.user
        student_id = payload['openid']
        seller = Student.objects.get(sno=student_id)
        school = seller.school
        name = request.data.get('name')
        price = request.data.get('price')
        description = request.data.get('description')
        adress = request.data.get('adress')
        stock_quantity = request.data.get('stock_quantity')
        aut = request.data.get('aut')
        created_at = request.data.get('created_at')
        publisher = request.data.get('publisher')
        category = request.data.get('category')

        product = Product.objects.create(seller=seller, school=school, name=name, price=price, description=description,
                                         adress=adress, aut=aut, created_at=created_at, publisher=publisher,
                                         stock_quantity=stock_quantity,
                                         category=category)
        id = product.id
        notification = Notification.objects.create(product=product, user=seller, content='', type='上架成功')
        return Response({'code': 1001, 'id': id})

    def put(self, request):
        payload = request.user
        product_id = request.data['product_id']
        product = Product.objects.get(id=product_id)
        serializer = ProductSerializer(product, data=payload)
        if serializer.is_valid():
            serializer.save()
            return Response({'code': 1001, 'data': serializer.data})
        return Response({'code': -1, 'data': serializer.errors})

    def delete(self, request):
        product_id = request.data['product_id']
        product = Product.objects.get(id=product_id)
        try:
            product.delete()
            return Response({'code': 1001, 'data': product.id})
        except Exception as e:
            return Response({'code': -1, 'data': str(e)})


class UploadProductImage(APIView):

    def post(self, request):
        data = request.data
        product_id = data.get('id')
        product = Product.objects.get(id=product_id)
        rev_file = request.data.get('image')
        # 判断，是否有文件
        if not rev_file:
            return Response({'code': 0, 'msg': '图片不存在！'})
        # 获得一个唯一的名字： uuid +hash
        new_name = get_random_str()
        # 准备写入的URL
        file_path = os.path.join(settings.MEDIA_ROOT, 'product_img', new_name + os.path.splitext(rev_file.name)[1])
        print(file_path)
        # 开始写入到本次磁盘
        try:
            f = open(file_path, 'wb')
            # 多次写入
            for i in rev_file.chunks():
                f.write(i)
            # 要关闭
            f.close()
            # 返回
            # product.image = new_name + os.path.splitext(rev_file.name)[1]
            # product.save()
            ProductImage.objects.create(product=product, img=new_name + os.path.splitext(rev_file.name)[1])
            return Response({'code': 1001, 'name': new_name + os.path.splitext(rev_file.name)[1]})
        except Exception as e:
            return Response({'code': -1, 'msg': str(e)})


class SchoolView(APIView):
    authentication_classes = []

    def get(self, request):
        schools = School.objects.all()
        try:
            serializer = SchoolSerializer(schools, many=True)
            school_names = [school['name'] for school in serializer.data]
            return Response({'code': 1001, 'data': school_names})
        except Exception as e:
            return Response({'code': -1, 'msg': str(e)})


class CreateOrderAPIView(APIView):

    def post(self, request, *args, **kwargs):
        payload = request.data
        student_id = payload['openid']
        student = Student.objects.get(sno=student_id)  # 买家
        buyer = student
        address = ''

        # 从请求中获取订单项
        order_items_data = request.data.get('order_items', [])

        # 存储每个卖家的订单
        orders = {}  # 存储每个卖家的订单

        # 检查产品库存并收集订单详细信息
        for item_data in order_items_data:
            product_id = item_data.get('product_id')
            quantity = item_data.get('quantity')
            address = item_data.get('address')  # 假设每个项都提供地址

            try:
                # 获取产品信息
                product = Product.objects.get(id=product_id)

                # 检查产品库存是否足够
                if product.stock_quantity < quantity:
                    return Response({"error": f"库存不足: {product.name}"}, status=status.HTTP_400_BAD_REQUEST)

                    # 初始化订单信息
                seller = product.seller
                total_amount = product.price * quantity

                # 如果卖家还没有订单，初始化新的订单
                if seller not in orders:
                    orders[seller] = {
                        'total_amount': 0,
                        'items': []
                    }

                    # 更新卖家的订单信息
                orders[seller]['total_amount'] += total_amount
                orders[seller]['items'].append((product, quantity))

            except Product.DoesNotExist:
                return Response({"error": f"产品不存在: {product_id}"}, status=status.HTTP_404_NOT_FOUND)

                # 从请求中提取额外字段
        shipping_method = payload.get('shipping_method', '快递')  # 默认送货方式
        payment_info = payload.get('payment_info', '')
        ad_info = payload.get('ad_info', '')
        note = payload.get('note', '')

        # 处理每个卖家的订单
        with transaction.atomic():
            for seller, order_data in orders.items():
                total_amount = order_data['total_amount']

                # 创建订单，填充所有字段
                order = Order(
                    buyer=buyer,
                    seller=seller,
                    total_amount=total_amount,
                    Shipping_method=shipping_method,
                    status='待支付',  # 默认状态
                    payment_info=payment_info,
                    ad_info=ad_info,
                    note=note
                )
                order.save()

                # 创建订单项并更新库存
                for product, quantity in order_data['items']:
                    OrderItem.objects.create(order=order, product=product, quantity=quantity,
                                             price_per_item=product.price)

                    # 更新库存数量
                    product.stock_quantity -= quantity
                    product.save()

                    # 返回成功响应
        return Response({"code": 1001, "message": "订单创建成功", "orders": [order.id for order in orders]},
                        status=status.HTTP_201_CREATED)

    # class PaymentAPIView(APIView):


#
#     def post(self, request, order_id):
#         try:
#             order = Order.objects.get(id=order_id)
#
#             # 检查订单状态（比如是否已经支付）
#             if order.status != 'pending':
#                 return Response({"error": "订单状态不允许进行支付"}, status=status.HTTP_400_BAD_REQUEST)
#
#             amount_to_pay = order.total_amount
#
#             # 从请求中获取支付信息
#             payment_data = request.data.get('payment_info', {})
#             payment_method = payment_data.get('method')
#
#             # 此处可以添加支付网关的逻辑
#             if not self.process_payment(payment_method, amount_to_pay):
#                 return Response({"error": "支付失败"}, status=status.HTTP_400_BAD_REQUEST)
#
#             # 如果支付成功，更新订单和库存
#             with transaction.atomic():
#                 order.status = 'paid'  # 更新订单状态
#                 order.save()
#
#                 # 更新库存，假设每个订单项都保存了商品数量
#                 for item in order.order_items.all():
#                     item.product.stock_quantity -= item.quantity
#                     item.product.save()
#
#                 # 创建支付记录
#                 payment = Payment.objects.create(
#                     order=order,
#                     amount=amount_to_pay,
#                     method=payment_method,
#                     status='completed'  # 假设支付成功状态
#                 )
#
#             # 返回支付成功响应
#             return Response({
#                 "message": "支付成功",
#                 "order_id": order.id,
#                 "payment_id": payment.id,
#             }, status=status.HTTP_201_CREATED)
#
#         except Order.DoesNotExist:
#             return Response({"error": "订单不存在"}, status=status.HTTP_404_NOT_FOUND)
#         except Exception as e:
#             return Response({"error": str(e)}, status=status.HTTP_500_INTERNAL_SERVER_ERROR)
#
#     def process_payment(self, method, amount):
#         # 实现您自己的支付处理逻辑
#         # 模拟支付成功
#         if method in ['credit_card', 'paypal']:  # 支持的支付方式示例
#             return True  # 假设支付成功
#         return False  # 支付失败

#         if method in ['credit_card', 'paypal']:  # 支持的支付方式示例
#             return True  # 假设支付成功
#         return False  # 支付失败

class CartListView(APIView):

    def post(self, request):
        payload = request.user
        student_id = payload['openid']
        student = Student.objects.get(sno=student_id)
        product_id = request.data['product_id']
        # 获取或创建购物车
        cart, created = Cart.objects.get_or_create(student=student)
        # 获取商品对象
        product = Product.objects.get(id=product_id)
        quantity = 1  # 默认为1
        # 尝试获取或创建购物车项
        cart_item, created = CartItem.objects.get_or_create(cart=cart, product=product, defaults={'quantity': quantity})
        # 如果购物车项已经存在，增加数量
        if not created:
            cart_item.quantity += 1
            cart_item.save()

        return Response({'code': 1001, 'msg': '添加购物车成功！'})

    def get(self, request):
        payload = request.user

    def get(self, request):
        payload = request.user
        student_id = payload['openid']
        student = Student.objects.get(sno=student_id)
        cart, created = Cart.objects.get_or_create(student=student)
        cart_items = CartItem.objects.filter(cart=cart)
        serializer = CartItemSerializer(cart_items, many=True)
        return Response({'code': 1001, 'data': serializer.data})

    def put(self, request):
        payload = request.user
        student_id = payload['openid']
        student = Student.objects.get(sno=student_id)
        product_id = request.query_params.get('product_id')
        method = request.query_params.get('method')
        cart = Cart.objects.get(student=student)
        cart_item = CartItem.objects.get(Q(cart=cart) & Q(product_id=product_id))
        if method == 'add':
            cart_item.quantity += 1
        elif method == 'remove':
            cart_item.quantity -= 1
        cart_item.save()
        return Response({'code': 1001, 'data': cart_item.quantity})

    def delete(self, request):
        payload = request.user
        student_id = payload['openid']
        student = Student.objects.get(sno=student_id)
        cart = Cart.objects.get(student=student)
        product_id = request.query_params.get('product_id')
        cart_item = CartItem.objects.get(Q(cart=cart) & Q(product_id=product_id))
        cart_item.delete()
        return Response({'code': 1001, 'data': '删除成功！'})


class GetChat(APIView):

    def get(self, request):
        friend_nickname = request.query_params.get('nickname')
        friend = Student.objects.get(nickname=friend_nickname)
        payload = request.user
        student_id = payload['openid']
        student = Student.objects.get(sno=student_id)  # 买家
        chat = ChatMessage.objects.filter(
            Q(sender=student, receiver=friend) | Q(sender=friend, receiver=student)
        ).order_by('timestamp')
        try:
            # 将未读消息标记为已读
            chat.filter(is_read=False).update(is_read=True)
            serializer = ChatMessageSerializer(chat, many=True)
            return Response({'code': 1001, 'data': serializer.data})
        except Exception as e:
            return Response({'code': -1, 'msg': str(e)})


class GetFriendsAPIView(APIView):
    def get(self, request):
        payload = request.user
        student_id = payload['openid']

        try:
            # 获取当前学生
            student = Student.objects.get(sno=student_id)
            # 获取朋友列表
            friends = student.friends.all()

            # 准备响应数据
            data = []  # 存储每个朋友的相关数据

            for friend in friends:
                # 计算未读消息数量
                unread_message = ChatMessage.objects.filter(
                    Q(sender=friend, receiver=student, is_read=False)
                ).count()

                # 获取与该朋友之间的最后一条消息
                recent_messages = ChatMessage.objects.filter(
                    Q(sender=student, receiver=friend) | Q(sender=friend, receiver=student)
                ).order_by('-timestamp')

                # 初始化last_time和content
                last_time = None
                content = None

                if recent_messages.exists():
                    last_message = recent_messages.first()  # 获取最后一条消息

                    # 获取消息的时间戳和内容
                    last_time = last_message.timestamp
                    content = last_message.message  # 假设您在 ChatMessage 中有 message 字段

                # 使用 StudentSerializer 生成朋友对象的数据
                friend_data = StudentSerializer(friend).data
                # 添加最新消息的信息到朋友对象中
                friend_data['last_time'] = last_time
                friend_data['content'] = content
                friend_data['unread_message'] = unread_message

                # 将更新后的朋友对象添加到返回的数据中
                data.append(friend_data)
            # print(data)
            return Response({'code': 1001, 'data': data})
        except Exception as e:
            print(e)
            return Response({'code': -1, 'msg': str(e)})


class ReportView(APIView):
    def post(self, request):
        payload = request.user
        student_sno = payload['openid']
        user = Student.objects.get(sno=student_sno)
        target_type = request.data.get('target_type')
        target_id = request.data.get('target_id')
        reason = request.data.get('reason')
        school = user.school
        print(request.data.get('title'))
        title = request.data.get('title')
        print(title)
        if target_type == 'product':
            try:
                product = Product.objects.get(id=target_id)
                print(product)
                img = ProductImage.objects.filter(product_id=target_id).first().img
                print(img)
                report = Report(user=user, target_type=target_type, target_id=target_id, reason=reason, img=img,
                                school=school, title=title)
            except Product.DoesNotExist:
                return Response({'code': -1, 'msg': '未找到product'}, status=status.HTTP_404_NOT_FOUND)
        elif target_type == 'post':
            try:
                post = Post.objects.get(id=target_id)
                img = PostImage.objects.filter(post_id=target_id).first().image
                report = Report(user=user, target_type=target_type, target_id=target_id, reason=reason, img=img,
                                school=school, title=title)
            except Post.DoesNotExist:
                return Response({'code': -1, 'msg': '未找到post'})
        else:
            return Response({'code': -1, 'msg': '无效的type'})

        report.save()
        serializer = ReportSerializer(report)
        return Response({'code': 1001, 'msg': '举报成功！'})

    def get(self, request):
        payload = request.user
        school_id = payload['id']
        school = School.objects.get(id=school_id)
        school_name = school.name
        reports = Report.objects.filter(school=school_name)
        serializer = ReportSerializer(reports, many=True)
        return Response(serializer.data)


class GetProductsAPIView(APIView):
    def get(self, request):
        # payload = request.user
        ID = request.query_params.get('ID')
        try:
            print('拿到的ID是', ID)
            products = Product.objects.get(id=ID)
        except Exception as e:
            return Response({'code': -1, 'msg': str(e)})
        serializer = ProductSerializer(products, many=False)
        return Response({'code': 1001, 'data': serializer.data})


class GetPostsAPIView(APIView):
    def get(self, request):
        # payload = request.user
        ID = request.query_params.get('id')
        print(ID)
        posts = Post.objects.get(id=ID)
        serializer = PostSerializer(posts, many=False)
        return Response({'code': 1001, 'data': serializer.data})


class AgreeReportView(APIView):
    def post(self, request):
        # payload = request.user
        # student_id = payload['openid']
        data = request.data
        ID = data['id']
        print(ID)
        report_id = data['report_id']
        print(report_id)
        report = Report.objects.get(id=report_id)
        type = data['type']
        print(type)
        if type == 'product':
            print('更改前', report.status)
            report.status = '同意'
            print('更改后', report.status)
            report.save()
            product = Product.objects.get(id=ID)
            product.status = '已下架'
            product.save()
            return Response({'code': 1001, 'data': 'success'})

        elif type == 'post':
            report.status = '已处理'
            post = Post.objects.get(id=ID)
            post.status = '违规'
            post.save()
            return Response({'code': 1001, 'data': 'success'})

        return Response({'code': -1})

    def get(self, request):
        payload = request.user
        school_id = payload['id']
        school = School.objects.get(id=school_id)
        reports = Report.objects.filter(Q(school=school) & Q(status='待处理'))
        serializer = ReportSerializer(reports, many=True)
        return Response(serializer.data)


class RejectReportView(APIView):

    def post(self, request):
        data = request.data
        ID = data['id']
        report_id = data['report_id']
        report = Report.objects.get(id=report_id)
        type = data['type']
        print(type)
        if type == 'product':
            report.status = '拒绝'
            report.save()
            product = Product.objects.get(id=ID)
            return Response({'code': 1001, 'data': 'success'})

        elif type == 'post':
            report.status = '拒绝'
            post = Post.objects.get(id=ID)
            return Response({'code': 1001, 'data': 'success'})

        return Response({'code': -1})

    def get(self, request):
        payload = request.user
        school_id = payload['id']
        school = School.objects.get(id=school_id)
        # 更改查询条件，查询该学校的同意或拒绝的report
        reports = Report.objects.filter(Q(school=school) & (Q(status='同意') | Q(status='拒绝')))
        serializer = ReportSerializer(reports, many=True)
        return Response(serializer.data)


class SendNoticeView(APIView):
    def post(self, request):
        payload = request.user
        data = request.data
        user = data['user']
        Type = data['type']
        content = data['reason']
        product_id = data['product_id']
        product = Product.objects.get(id=product_id)
        notification = Notification.objects.create(user=user, content=content, type=Type,
                                                   product_id=product_id).order_by('created_at')
        return Response({'code': 1001, 'data': 'success'})

    def get(self, request):
        payload = request.user
        student_id = payload['openid']
        notifications = Notification.objects.filter(user=student_id)
        notifications.filter(user=student_id).update(is_read=True)
        serializer = NotificationSerializer(notifications, many=True)
        return Response({'code': 1001, 'data': serializer.data})


class GetNotice(APIView):
    def get(self, request):
        recent_message = None
        payload = request.user
        student_id = payload['openid']
        student = Student.objects.get(sno=student_id)
        school = student.school
        img = student.image
        name = school.name
        un_read = Notification.objects.filter(user=student_id, is_read=False).count()

        # 查询最近的通知
        recent_notification = Notification.objects.filter(user=student_id).order_by('-created_at').first()

        if recent_notification:
            recent_message_type = recent_notification.type
            time = recent_notification.created_at  # 在此处安全访问 created_at
        else:
            recent_message_type = ''
            time = None  # 如果没有通知，设置为 None 或其他适当的值

        # 根据通知类型设置最近消息
        if recent_message_type == '举报':
            recent_message = '您有一条举报消息'
        elif recent_message_type == '上架成功':
            recent_message = '您成功上架一件商品！'
        elif recent_message_type == '':
            recent_message = None
        else:
            recent_message = '您售出了一件商品！'

        # 准备响应数据
        data = {
            'un_read': un_read,
            'recent_message': recent_message,
            'name': name,
            'image': img,
            'time': time,  # 如果没有通知，将返回 None
        }

        return Response({'code': 1001, 'data': data})


class MySellProductsAPIView(APIView):
    def get(self, request):
        payload = request.user
        sno = payload['openid']
        student = Student.objects.get(sno=sno)
        products = Product.objects.filter(seller=student)
        serializer = ProductSerializer(products, many=True)
        print('我卖的商品', serializer.data)
        return Response({'code': 1001, 'data': serializer.data})


class MyProductsAPIView(APIView):
    def get(self, request):
        payload = request.user
        sno = payload['openid']
        student = Student.objects.get(sno=sno)
        orders = Order.objects.filter(seller=student)

        # 初始化一个列表来存储所有订单项
        items = []

        # 遍历每个订单，获取其订单项
        for order in orders:
            order_items = OrderItem.objects.filter(order=order)
            items.extend(order_items)

        # 在这里，你可以根据需要对 items 进行序列化或其他处理
        # 例如，你可以创建一个 OrderItemSerializer 并序列化 items
        serializer = OrderItemSerializer(items, many=True)
        print('我的商品', serializer.data)
        return Response({'code': 1001, 'data': serializer.data})


class AddFriend(APIView):
    def post(self, request):
        payload = request.user
        student_id = payload['openid']
        friend_id = request.data.get('friend_id')
        student = Student.objects.get(sno=student_id)
        friend = Student.objects.get(sno=friend_id)
        student.friends.add(friend)
        student.save()
        return Response({'code': 1001, 'data': 'success'})


class OrderView(APIView):
    def post(self, request):
        print(request.data)
        payload = request.user
        student_id = payload['openid']
        student = Student.objects.get(sno=student_id)
        cart = Cart.objects.get(student=student)
        ad_info = request.data.get('address')
        try:
            buyer = Student.objects.get(sno=student_id)
        except Student.DoesNotExist:
            return Response({'code': 1002, 'data': 'Buyer not found'}, status=404)

        with transaction.atomic():
            for item in request.data.get('Total', []):  # 从 "Total" 提取数据
                seller_data = item['seller']  # 提取 seller 的数据
                seller_sno = seller_data['sno']  # 获取 seller 的 sno
                try:
                    seller = Student.objects.get(sno=seller_sno)
                except Student.DoesNotExist:
                    return Response({'code': 1003, 'data': 'Seller not found'}, status=404)

                total_amount = float(item['totalThis'])  # 确保 totalThis 存在并转换为 float
                shipping_method = item['Shipping_method']
                note = item['note'] if 'note' in item else ""  # 确保 note 存在
                products = item['product']  # 获取产品列表

                # 创建订单
                order = Order(
                    seller=seller,
                    shipping_method=shipping_method,
                    note=note,
                    buyer=buyer,
                    total_amount=total_amount,
                    ad_info=ad_info
                )
                order.save()

                # 处理每个产品
                for product_id in products:
                    try:
                        # bug修复: 改为get方法
                        cart_item = CartItem.objects.get(product_id=product_id, cart=cart)
                        product_instance = cart_item.product
                        print(cart_item.product)
                    except CartItem.DoesNotExist:
                        # 如果购物车项目不存在，则创建一个新的购物车项目
                        product_instance = Product.objects.get(id=product_id)
                        cart_item = CartItem.objects.create(cart=cart, product_id=product_id, quantity=1)

                    quantity = cart_item.quantity
                    product = cart_item.product
                    print(product)
                    price_per_item = product.price  # 假设那里有获取价格的方法

                    OrderItem.objects.create(
                        order=order,
                        quantity=quantity,
                        product=product,
                        price_per_item=price_per_item
                    )

                    # 从购物车中删除已购买的产品
                    cart_item.delete()
                    user = seller
                    Type = '售出'
                    content = ''
                    notification = Notification.objects.create(user=user, content=content, type=Type,
                                                               product=product_instance)
        return Response({'code': 1001, 'data': 'success'})

    def get(self, request):
        payload = request.user
        student_id = payload['openid']
        orders = Order.objects.filter(seller=student_id)
        serializer = OrderSerializer(orders, many=True)
        return Response({'code': 1001, 'data': serializer.data})


class NoticeView(APIView):
    def post(self, request):
        payload = request.user
        student_id = payload['openid']
        student = Student.objects.get(sno=student_id)
        notifications = Notification.objects.filter(user=student_id)
        notifications.filter(user=student_id).update(is_read=True)
        serializer = NotificationSerializer(notifications, many=True)
        return Response({'code': 1001, 'data': serializer.data})


# from django.db.models import Q

# class ProductSearchView(APIView):
#     def get(self, request):
#         query = request.query_params.get('search', None)
#         if query:
#             # 使用正确的查找类型来过滤产品名称
#             products = Product.objects.filter(
#                 Q(name__icontains=query) |
#                 Q(description__icontains=query) |
#                 Q(seller__name__icontains=query) |
#                 Q(school__name__icontains=query) |
#                 Q(category__name__icontains=query)
#             )
#             serializer = ProductSerializer(products, many=True)
#             return Response({'code': 1001, "message": serializer.data})
#         else:
#             return Response({'code': -1, "message": '搜索内容不能为空'})

class ProductSearchView(APIView):
    def get(self, request):
        query = request.query_params.get('search', None)
        if query:
            # 使用 Q 对象进行多个字段的模糊查询
            products = Product.objects.filter(
                Q(seller__name__icontains=query) |  # 假设 Student 模型有一个 username 字段
                Q(school__name__icontains=query) |  # 假设 School 模型有一个 name 字段
                Q(name__icontains=query) |
                Q(description__icontains=query) |
                Q(category__icontains=query)
            )
        else:
            products = Product.objects.all()  # 如果没有查询关键词，返回所有产品

        serializer = ProductSerializer(products, many=True)
        return Response({'code': 1001, 'data': serializer.data})
